"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : DMS分布式锁
Case Name   : 非资源池，没有声明锁模式，缺省是否为模式access exclusive
Create At   : 2023/4/21
Owner       : opentestcase033
Description :
    1.设置资源池化参数ss_enable_dms=off
    2.查看视图pg_locks，统计锁信息
    3.开启事务，创建表，查询视图pg_locks，表是否加accessexclusivelock锁
    4.清理环境
Expect:
    1.设置成功
    2.成功
    3.加row exclusive锁
    4.成功
History     :
"""

import os
import unittest

from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant


class DmsOck(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.common = Common('PrimaryDbUser')
        self.constant = Constant()
        self.tb_name = 't_dms_ock_0012'
        self.index_name = 'i_dms_ock_0012'
        self.ss_enable_dms = self.common.show_param('ss_enable_dms')
        self.flag = 0

    def test_dms_ock(self):
        text1 = '-----step1:设置资源池化参数ss_enable_dms=off;expect:成功-----'
        self.log.info(text1)
        if 'off' != self.ss_enable_dms:
            self.flag = 1
            guc_res = self.pri_sh.execute_gsctl(
                'set', self.constant.GSGUC_SUCCESS_MSG, 'ss_enable_dms=off')
            self.log.info(guc_res)
            self.assertTrue(guc_res, f"设置ss_enable_dms参数失败:{text1}")
            stop_res = self.pri_sh.exec_cm_ctl('stop')
            self.log.info(stop_res)
            start_res = self.pri_sh.exec_cm_ctl('start')
            self.log.info(start_res)

        text2 = '-----step2:查看视图pg_locks，统计锁信息;expect:查询0-----'
        self.log.info(text2)
        select_lock = f"select count(*) from pg_locks " \
                      f"where mode = 'AccessExclusiveLock' " \
                      f"and locktype = 'relation';"
        lock_res = self.pri_sh.execut_db_sql(select_lock)
        self.log.info(lock_res)
        self.assertEqual('0', lock_res.splitlines()[2].strip(),
                         f"执行失败:{text2}")

        text3 = '-----step3:开启事务，为表加shar row exclusive锁，查询' \
                '视图pg_locks，表是否加锁成功;expect:加row exclusive锁-----'
        self.log.info(text3)
        sql = f"start transaction;" \
              f"create table {self.tb_name}(sk integer," \
              f"id char(16),name varchar(20),sq_ft integer);" \
              f"insert into {self.tb_name} values(004,'sk4','tt',3332);" \
              f"select locktype,database,relation,transactionid," \
              f"classid,virtualtransaction,mode,granted,fastpath " \
              f"from pg_locks, pg_class " \
              f"where relation = oid and relname = '{self.tb_name}';" \
              f"select count(*) from pg_locks " \
              f"where mode = 'AccessExclusiveLock' " \
              f"and locktype = 'relation';"
        sql_res = self.pri_sh.execut_db_sql(sql)
        self.log.info(sql_res)
        self.assertIn(self.constant.START_TRANSACTION_SUCCESS_MSG,
                      sql_res, f"执行失败:{text3}")
        self.assertIn(self.constant.CREATE_TABLE_SUCCESS, sql_res,
                      f"建表失败:{text3}")
        self.assertIn('AccessExclusiveLock', sql_res, f"执行失败:{text3}")
        self.assertEqual('1', sql_res.splitlines()[-2].strip(),
                         f"执行失败:{text3}")

    def tearDown(self):
        text4 = '-----step4:清理环境 expect:成功-----'
        self.log.info(text4)
        drop_db_res = self.pri_sh.execut_db_sql(
            f"drop table if exists {self.tb_name} cascade;")
        self.log.info(drop_db_res)
        if self.flag:
            guc_res = self.pri_sh.execute_gsctl(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                f'ss_enable_dms={self.ss_enable_dms}')
            self.log.info(guc_res)
            restart_db = self.pri_sh.restart_db_cluster()
            self.log.info(restart_db)
            self.assertTrue(guc_res, f"恢复ss_enable_dms参数失败:{text4}")
            self.assertTrue(restart_db, f"重启数据库失败:{text4}")
        self.assertIn(self.constant.DROP_TABLE_SUCCESS,
                      drop_db_res, f"删表失败:{text4}")
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
